<?php

class URIRouter
{
	private $map;
	
	public function __construct()
	{
		$this->map = array();
	}
	
	public function connect(URIPattern $pattern)
	{
		array_push($this->map, $pattern);
	}
	
	public function connect_router(URIPattern $pattern, URIRouter $router)
	{
		array_push($this->map, array($pattern, $router));
	}
	
	public function match_address($address)
	{
		foreach ($this->map as $key => $pattern)
		{
			if ($pattern instanceof URIPattern)
			{
				if ($pattern->matches($address) !== false)
				{
					return array(
						'controller' => $pattern->get_controller(),
						'view' => $pattern->get_view(),
						'args' => $pattern->match_args($address)
					);
				}
			}
			elseif (is_array($pattern))
			{
				// This has an included router; if the local pattern matches,
				// try the inner router
				$base_match = $pattern[0]->matches($address);
				if ($base_match !== false)
				{
					$submatch = ($pattern[1]->match_address(
						(string)substr($address, strlen($base_match))
					));
					if (!is_null($submatch))
					{
						// Included router matched
						$controller = $submatch['controller']?:$pattern[0]->get_controller();
						$view = $submatch['view']?:$pattern[0]->get_view();
						$args = array_merge($pattern[0]->match_args($address),
							$submatch['args']);
						return array(
							'controller' => $controller,
							'view' => $view,
							'args' => $args
						);
					}
				}
			}
		}
		
		// Nothing matched
		throw new Http404Exception('Nothing matched URI');
	}
	
	public function has_patterns()
	{
		return count($this->map) > 0;
	}
}

?>